package com.xbongbong.paas.help.symbol;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ql.util.express.OperatorOfNumber;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.BusinessConstant;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2021/01/07 14:31
 */
public abstract class AbstractSymbolHandle  {

    /**
     * 等于
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean equals(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;
    /**
     * 不等于
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean noEquals(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;
    /**
     * 包含
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean like(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;

    /**
     * 包含
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean noLike(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;
    /**
     * 等于任意一个
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean in(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;
    /**
     * 等于
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean noIn(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;
    /**
     * 等于
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean empty(PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;
    /**
     * 等于
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean noEmpty(PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;
    /**
     * 等于
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean greaterEqual(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;

    /**
     * 等于
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return abstract 
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean lessEqual(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;
    /**
     * 等于
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return abstract
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean greaterThan(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;
    /**
     * 等于
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return abstract
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean lessThan(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;
    /**
     * 等于
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean range(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;

    public abstract boolean dynamic(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;

    /**
     * 等于
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean include(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;
    /**
     * 同时包含
     * @param target
     * @param source
     * @param fieldAttrEntity
     * @return boolean
     * @author 吴峰
     * @date 2021/1/7 14:30
     * @throws XbbException
     */
    public abstract boolean allInclude(Object target, PaasFormDataEntity source, FieldAttrEntity fieldAttrEntity) throws XbbException;


    /**
     * 大于等于某个值
     * @param source 数据
     * @param target 目标数据
     * @return boolean true：大于等于；false：小于
     * @author 吴峰
     * @date 2021/1/8 17:21
     * @throws XbbException
     */
    public boolean greaterEqual(Number source, Number target) throws XbbException {
        int result = OperatorOfNumber.compareNumber(source, target);
        return result >= 0;
    }
    /**
     * 小于等于某个值
     * @param source 数据
     * @param target 目标数据
     * @return boolean true：小于等于；false：大于
     * @author 吴峰
     * @date 2021/1/8 17:21
     * @throws XbbException
     */
    public boolean lessEqual(Number source, Number target) throws XbbException {
        int result = OperatorOfNumber.compareNumber(source, target);
        return result <= 0;
    }
    /**
     * 大于某个值
     * @param source 数据
     * @param target 目标数据
     * @return boolean true：大于；false：小于等于
     * @author 吴峰
     * @date 2021/1/8 17:21
     * @throws XbbException
     */
    public boolean greaterThan(Number source, Number target) throws XbbException {
        int result = OperatorOfNumber.compareNumber(source, target);
        return result > 0;
    }
    /**
     * 小于某个值
     * @param source 数据
     * @param target 目标数据
     * @return boolean true：小于；false：大于等于
     * @author 吴峰
     * @date 2021/1/8 17:21
     * @throws XbbException
     */
    public boolean lessThan(Number source, Number target) throws XbbException {
        int result = OperatorOfNumber.compareNumber(source, target);
        return result < 0;
    }
    /**
     * 某个数据是否在范围之内
     * @param min 最小值
     * @param max 最大值
     * @param source 数据
     * @return boolean true：在范围之内；false：在范围之外
     * @author 吴峰
     * @date 2021/1/8 17:21
     * @throws XbbException
     */
    public boolean range(Number min, Number max, Number source) throws XbbException {
        // 遵循左闭右闭原则，方便客户理解
        // source应该大于等于min data >= min
        int start = OperatorOfNumber.compareNumber(source, min);
        // source 应该小于max
        int end = OperatorOfNumber.compareNumber(max, source);
        return start>=0 && end >= 0;
    }

    public boolean dynamic(Number min, Number max, Number source) throws XbbException {
        // 遵循左闭右开原则
        // source应该大于等于min data >= min
        int start = OperatorOfNumber.compareNumber(source, min);
        // source 应该小于max
        int end = OperatorOfNumber.compareNumber(max, source);
        return start>=0 && end > 0;
    }

    public boolean equals(Object target, Object source) throws XbbException {
        return Objects.equals(target, source);
    }

    public boolean noEquals(Object target, Object source) throws XbbException {
        return !Objects.equals(target, source);
    }

    /**
     * 为空
     * @param source
     * @return true：为空； false：不为空
     * @throws XbbException
     */
    public static boolean empty(Object source) throws XbbException {
        if (Objects.isNull(source) || StringUtil.isEmpty(source.toString())) {
            return true;
        } else if (source instanceof List) {
            List<Object> list = JSON.parseArray(JSON.toJSONString(source));
            return CollectionsUtil.isEmpty(list);
        } else if (source instanceof Map) {
            JSONObject address = JSON.parseObject(JSON.toJSONString(source));
            if (Objects.isNull(address) || address.isEmpty()) {
                return true;
            }
            if (address.containsKey(BusinessConstant.PROVINCE)) {
                return StringUtil.isEmpty(address.getString(BusinessConstant.PROVINCE));
            }
        }
        return false;
    }

    /**
     * 不能为空
     * @param source
     * @return
     * @throws XbbException
     */
    public static boolean noEmpty(Object source) throws XbbException {
        return !empty(source);
    }

    /**
     * 等于任意一个，即源数据存在在目标数据列表中
     * @param target 目标数据列表 如： ["数据1", "数据2"]
     * @param object 源数据 如：数据1
     * @return boolean
     * @author 吴峰
     * @date 2021/1/8 17:17
     * @throws XbbException
     */
    public boolean in(Object target, Object object) throws XbbException {
        List<Object> list = JSON.parseArray(JSON.toJSONString(target), Object.class);
        return list.contains(object);
    }

    /**
     * 不等于任意一个， 即源数据不存在在目标数据列表中
     * @param target 目标数据 如：["数据1", "数据2"]
     * @param object 源数据 如：数据1
     * @return
     * @throws XbbException
     */
    public boolean noIn(Object target, Object object) throws XbbException {
        return !in(target, object);
    }


}
